package outbound_crowd

import (
	"context"
	"git.mycaigou.com/gfyx/common/tenant_db"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/common/constants"
	"gorm.io/gorm"
	"time"
)

type outboundCrowdRepos struct {
	tenant_db.TenantDB
}

func NewOutboundCrowdRepos() OutboundCrowdReposIface {
	return &outboundCrowdRepos{}
}

func (g *outboundCrowdRepos) AddOutboundCrowd(ctx context.Context, data *OutboundCrowd) (int32, error) {
	data.CreatedOn = time.Now()
	data.ModifiedOn = time.Now()
	err := g.GetTenantDB(ctx).Create(&data).Error
	if err != nil {
		return 0, err
	}
	return data.Id, nil
}

func (g *outboundCrowdRepos) SaveOutboundCrowd(ctx context.Context, data *OutboundCrowd) error {
	data.ModifiedOn = time.Now()
	err := g.GetTenantDB(ctx).Save(data).Error
	if err != nil {
		return err
	}
	return nil
}

func (g *outboundCrowdRepos) GetOutboundCrowd(ctx context.Context, id int32) (*OutboundCrowd, error) {
	outboundCrowd := &OutboundCrowd{}
	err := g.GetTenantDB(ctx).
		Table(OutboundCrowd{}.TableName()).
		Where("is_deleted = ?", constants.IsDeletedFalse).
		Where("id = ?", id).
		Order("created_on desc").First(outboundCrowd).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return outboundCrowd, err
	}
	return outboundCrowd, nil
}

func (g *outboundCrowdRepos) GetOutboundCrowdByName(ctx context.Context, crowdName string) (*OutboundCrowd, error) {
	outboundCrowd := &OutboundCrowd{}
	err := g.GetTenantDB(ctx).
		Table(OutboundCrowd{}.TableName()).
		Where("crowd_name = ?", crowdName).
		Where("is_deleted = ?", constants.IsDeletedFalse).
		Order("created_on desc").First(outboundCrowd).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return outboundCrowd, err
	}
	return outboundCrowd, nil
}

func (g *outboundCrowdRepos) GetOutboundCrowdRpa(ctx context.Context) (int64, *OutboundCrowd, error) {
	outboundCrowd := &OutboundCrowd{}
	var total int64
	err := g.GetTenantDB(ctx).
		Table(OutboundCrowd{}.TableName()).
		Where("type = ?", constants.CrowdTypeRpa).
		Where("is_deleted = ?", constants.IsDeletedFalse).
		Order("created_on desc").Count(&total).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return total, outboundCrowd, err
	}
	errFind := g.GetTenantDB(ctx).
		Where("type = ?", "RPA").
		Order("created_on desc").First(outboundCrowd).Error
	if errFind != nil && errFind != gorm.ErrRecordNotFound {
		return total, outboundCrowd, errFind
	}
	return total, outboundCrowd, nil
}

func (g *outboundCrowdRepos) GetOutboundCrowdPage(ctx context.Context, condition *GetCrowdListCondition, page int32, pageSize int32) ([]*OutboundCrowd, int64, error) {
	outboundCrowdList := make([]*OutboundCrowd, 0)
	db := g.GetTenantDB(ctx).
		Table(OutboundCrowd{}.TableName()).
		Where("is_deleted = ?", constants.IsDeletedFalse)

	if condition.CrowdName != "" {
		db = db.Where("crowd_name like ? ", "%"+condition.CrowdName+"%")
	}
	if condition.Status != 0 {
		db = db.Where("status = ? ", condition.Status)
	}
	db = db.Order("created_on desc")
	var total int64
	db.Count(&total)
	err := db.Limit(int(pageSize)).
		Offset((int(page) - 1) * int(pageSize)).
		Find(&outboundCrowdList).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return nil, 0, db.Error
	}
	return outboundCrowdList, total, nil
}

func (g *outboundCrowdRepos) GetOutboundCrowdBatch(ctx context.Context, idList []int32) ([]*OutboundCrowd, error) {
	outboundCrowd := make([]*OutboundCrowd, 0)
	if len(idList) == 0 {
		return outboundCrowd, nil
	}

	db := g.GetTenantDB(ctx).
		Where("id in (?)", idList).
		Where("is_deleted = ?", constants.IsDeletedFalse).
		Order("created_on desc")

	err := db.Find(&outboundCrowd).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return outboundCrowd, err
	}

	return outboundCrowd, nil
}

func (g *outboundCrowdRepos) UpdateStatus(ctx context.Context, id int32, status int32) (bool, error) {
	err := g.GetTenantDB(ctx).
		Table(OutboundCrowd{}.TableName()).
		Where("id=?", id).
		Updates(map[string]interface{}{"status": status}).Error
	if err != nil {
		return false, err
	}
	return true, nil

}

func (g *outboundCrowdRepos) DeleteCrowd(ctx context.Context, id int32) (bool, error) {
	err := g.GetTenantDB(ctx).
		Table(OutboundCrowd{}.TableName()).
		Where("id=?", id).
		Updates(map[string]interface{}{"is_deleted": constants.IsDeletedTrue}).Error
	if err != nil {
		return false, err
	}
	return true, nil

}

func (g *outboundCrowdRepos) AddOutboundCrowdFile(ctx context.Context, data *OutboundCrowdFilePo) (*OutboundCrowdFilePo, error) {
	err := g.GetTenantDB(ctx).Table(data.TableName()).Create(data).Error
	if err != nil {
		return nil, err
	}
	return data, nil
}

func (g *outboundCrowdRepos) GetOutboundCrowdFileByCondition(ctx context.Context, condition map[string]interface{}) ([]*OutboundCrowdFilePo, error) {
	var list []*OutboundCrowdFilePo
	err := g.GetTenantDB(ctx).Table(OutboundCrowdFilePo{}.TableName()).Where(condition).Find(&list).Error
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, nil
		}
		return nil, err
	}
	return list, nil
}

func (g *outboundCrowdRepos) AddOutboundCrowdRuntime(ctx context.Context, data *OutboundCrowdRuntimePo) (*OutboundCrowdRuntimePo, error) {
	err := g.GetTenantDB(ctx).Table(data.TableName()).Create(data).Error
	if err != nil {
		return nil, err
	}
	return data, nil
}

func (g *outboundCrowdRepos) UpdateRuntimeStatus(ctx context.Context, id int32, status int32) error {
	err := g.GetTenantDB(ctx).Table(OutboundCrowdRuntimePo{}.TableName()).
		Where("id=?", id).Updates(map[string]interface{}{"status": status}).Error
	if err != nil {
		return err
	}
	return nil
}

func (g *outboundCrowdRepos) GetOutboundCrowdRuntimeByVersion(ctx context.Context, crowdId int32, crowdVersion int32) (*OutboundCrowdRuntimePo, error) {
	outboundCrowdRuntime := &OutboundCrowdRuntimePo{}
	err := g.GetTenantDB(ctx).
		Table(OutboundCrowdRuntimePo{}.TableName()).
		Where("is_deleted = ?", constants.IsDeletedFalse).
		Where("crowd_id = ?", crowdId).
		Where("crowd_version = ?", crowdVersion).
		Order("created_on asc").First(outboundCrowdRuntime).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return outboundCrowdRuntime, err
	}
	return outboundCrowdRuntime, nil
}
